package com.qlk.vorder.rest;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.qlk.common.utils.config.PropertiesHelper;
import com.qlk.common.utils.security.MD5Util;
import com.qlk.common.utils.serialize.JsonHelper;
import com.qlk.common.utils.wrap.WrapMapper;
import com.qlk.common.utils.wrap.Wrapper;
import com.qlk.vorder.domain.Orders;
import com.qlk.vorder.domain.ReserveSession;
import com.qlk.vorder.domain.SerialLog;
import com.qlk.vorder.domain.query.OrdersQuery;
import com.qlk.vorder.domain.query.ReserveSessionQuery;
import com.qlk.vorder.sdk.api.request.OrdersRequest;
import com.qlk.vorder.sdk.api.request.OrdersRequestDto;
import com.qlk.vorder.sdk.api.request.ReserveSessionRequestDto;
import com.qlk.vorder.sdk.api.response.OrdersResponseDto;
import com.qlk.vorder.service.OrdersService;
import com.qlk.vorder.service.ReserveSessionService;
import com.qlk.vorder.service.SerialLogService;
import com.qlk.vorder.utils.exceptions.Constant;

/**
 * 咨询订单REST服务：提供有关咨询订单的接口
 * 
 * @author zhaoyanan
 * @version 2016-7-28 14:14:01
 * 
 */
@Component
@Path("services")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public class OrdersResource {

	private final Log logger = LogFactory.getLog(this.getClass());

	@Autowired
	private OrdersService ordersService;
	@Autowired
	private ReserveSessionService reserveSessionService;
	@Autowired
	private SerialLogService serialLogService;

	/**
	 * 查询咨询订单信息
	 * 
	 * @param request
	 *            咨询订单请求参数
	 * @return 咨询订单返回对象
	 * 
	 */
	@POST
	@Path("/orders/getOrders")
	public Wrapper<?> getOrders(OrdersRequest request) {
		if (null == request || StringUtils.isBlank(request.getOrderids())) {
			this.logger.error("getOrders 传入参数有误");
			return WrapMapper.illegalArgument();
		}
		try {
			List<Orders> orders = ordersService.getBatchOrders(request);
			List<OrdersResponseDto> response = convertList(orders);
			return WrapMapper.ok().result(response);
		} catch (Exception e) {
			this.logger.error("查询咨询订单数据异常", e);
			return WrapMapper.error();
		}
	}

	/**
	 * 创建虚拟订单接口
	 * 
	 * @param request
	 *            接收参数
	 * @return 返回状态
	 * 
	 */
	@POST
	@Path("/orders/orderData")
	public Wrapper<?> orderData(OrdersRequestDto request) {
		boolean flagSerialLog = false;
		Wrapper<?> wrapper = null;
		SerialLog serialLog = new SerialLog();
		try {
			logger.info("创建虚拟订单接收参数:" + JsonHelper.toJson(request));
			if (null == request || StringUtils.isBlank(request.getOrderid()) || request.getTimestamp() == null
					|| StringUtils.isBlank(request.getSign()) || request.getOrderStatus() == null) {
				this.logger.error("getOrders 传入参数有误");
				serialLog.setResponseContent(JsonHelper.toJson(WrapMapper.illegalArgument()));
				return WrapMapper.illegalArgument();
			}
			String sign = "";
			// 签名校验
			sign = MD5Util.md5Hex(request.getOrderid() + PropertiesHelper.newInstance().getValue("vorder.task.sign"));
			logger.info("虚拟订单推入sign:" + request.getSign() + ">>>sign:" + sign);
			if (!sign.equals(request.getSign())) {
				logger.warn("》》》》》虚拟订单签名异常《《《《《");
				serialLog.setResponseContent(JsonHelper.toJson(WrapMapper.wrap(Constant.ERROR_SIGN, Constant.ERROR_SIGN_TEXT)));
				return WrapMapper.wrap(Constant.ERROR_SIGN, Constant.ERROR_SIGN_TEXT);
			}
			wrapper = ordersService.innerData(request);
			serialLog.setResponseContent(JsonHelper.toJson(wrapper));
			return wrapper;
		} catch (Exception e) {
			this.logger.error("创建虚拟订单异常", e);
			return WrapMapper.error();
		}finally{
			serialLog.setOrderid(request.getOrderid());
			serialLog.setOrderStatus(request.getOrderStatus());
			serialLog.setLogType("CREATE_VORDER");
			serialLog.setRequestContent(JsonHelper.toJson(request));
			if (wrapper != null && wrapper.getCode() == 200) {
				serialLog.setRequestStatus(Constant.LOG_STATUS_SUCCESS);
			} else {
				serialLog.setRequestStatus(Constant.LOG_STATUS_ERROR);
			}
			flagSerialLog = serialLogService.insert(serialLog);
			this.logger.info("创建虚拟订单，新增流水日志flagSerialLog:" + flagSerialLog);
		}
	}

	/**
	 * 创建订单会话接口
	 * 
	 * @param request
	 * @return
	 */
	@POST
	@Path("/orders/sessionData")
	public Wrapper<?> innerOrderSession(ReserveSessionRequestDto request) {
		boolean flag = false;
		boolean flagSerialLog = false;
		SerialLog serialLog = new SerialLog();
		try {
			logger.info("创建虚拟订单会话参数:" + JsonHelper.toJson(request));
			if (null == request || null == request.getOrderid() || null == request.getSessionId() || request.getStartTime() == null
					|| request.getSign() == null) {
				this.logger.error("innerOrderSession 传入参数有误");
				serialLog.setResponseContent("传入参数有误");
				return WrapMapper.illegalArgument();
			}
			String sign = "";
			// 签名校验
			sign = MD5Util.md5Hex(request.getOrderid() + PropertiesHelper.newInstance().getValue("vorder.task.sign"));
			logger.info("创建虚拟订单会话推入sign:" + request.getSign() + ">>>sign" + sign);
			if (!sign.equals(request.getSign())) {
				logger.warn("》》》》》虚拟订单会话签名异常《《《《《");
				serialLog.setResponseContent("签名异常创建虚拟订单会话推入sign:" + request.getSign() + ">>>sign" + sign);
				return WrapMapper.wrap(Constant.ERROR_SIGN, Constant.ERROR_SIGN_TEXT);
			}
			// 1:查询订单主表是否存在此单
			OrdersQuery ordersQuery = new OrdersQuery();
			ordersQuery.setOrderid(request.getOrderid());
			Orders orders = ordersService.getOrdersByOrderId(ordersQuery);
			if (orders == null) {
				serialLog.setResponseContent("单号不存在");
				return WrapMapper.illegalArgument().message("单号不存在");
			}
			// 根据sessionId查询数据是否存在
			ReserveSessionQuery queryBean = new ReserveSessionQuery();
			queryBean.setSessionId(request.getSessionId());
			int count = reserveSessionService.queryReserveBySessionIdCount(queryBean);
			if (count > 0) {
				serialLog.setResponseContent("sessionId已存在不能重复插入");
				return WrapMapper.illegalArgument().message("重复插入");
			}
			ReserveSession reserveSession = convertReserveSession(request);
			flag = reserveSessionService.insert(reserveSession);
			if (flag) {
				serialLog.setResponseContent("创建会话成功");
				return WrapMapper.ok();
			}
		} catch (Exception e) {
			serialLog.setResponseContent("创建会话异常");
			logger.error("创建会话异常", e);
			return WrapMapper.error();
		} finally {
			serialLog.setOrderid(request.getOrderid());
			serialLog.setLogType("CREATE_SESSION");
			serialLog.setCreateName(Constant.SYSTEM_NAME);
			serialLog.setRequestContent(JsonHelper.toJson(request));
			if (flag) {
				serialLog.setRequestStatus(Constant.LOG_STATUS_SUCCESS);
			} else {
				serialLog.setRequestStatus(Constant.LOG_STATUS_ERROR);
			}
			flagSerialLog = serialLogService.insert(serialLog);
			logger.info("创建虚拟订单，新增流水日志flagSerialLog:" + flagSerialLog);
		}
		return WrapMapper.error();
	}

	/** 会话数据转换 */
	private ReserveSession convertReserveSession(ReserveSessionRequestDto request) {
		ReserveSession reserveSession = new ReserveSession();
		reserveSession.setSessionId(request.getSessionId());
		reserveSession.setOrderid(request.getOrderid());
		reserveSession.setStartTime(request.getStartTime());
		reserveSession.setEndTime(request.getEndTime());
		reserveSession.setTimeLength(request.getTimeLength());
		reserveSession.setCreateName(Constant.SYSTEM_NAME);
		return reserveSession;
	}

	// 数据转换
	private OrdersResponseDto convert(Orders orders) {
		if (null == orders) {
			return null;
		}

		OrdersResponseDto ordersResponse = new OrdersResponseDto();
		BeanUtils.copyProperties(orders, ordersResponse);
		return ordersResponse;
	}

	// 数据转换
	private List<OrdersResponseDto> convertList(List<Orders> orderss) {
		if (CollectionUtils.isEmpty(orderss)) {
			return null;
		}

		List<OrdersResponseDto> list = new ArrayList<OrdersResponseDto>(orderss.size());
		for (Orders orders : orderss) {
			list.add(convert(orders));
		}
		return list;
	}

}
